package es.decloud.model;

import static javax.persistence.GenerationType.IDENTITY;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Indexed;

@Entity
@Table(name = "aula")
@Indexed
@XmlRootElement
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@NamedQueries({ @NamedQuery(name = "findAulaByNombre", query = "select a from Aula a where a.centro.id = :centro and a.nombre = :nombre ") })
public class Aula extends BaseObject implements Serializable {

	private static final long serialVersionUID = 7264475368611197876L;

	private Long id;
	private Centro centro;
	private String nombre;
	private String ubicacion;
	// private Date fechaCreacion;
	private Date fechaBaja;
	private Set<Usuario> educadoras = new HashSet<>(0);
	private Set<Alumno> alumnos = new HashSet<>(0);

	public Aula() {
	}

	public Aula(Centro centro, String nombre) {
		this.centro = centro;
		this.nombre = nombre;
		// this.fechaCreacion = fechaCreacion;
	}

	public Aula(Centro centro, String nombre, String ubicacion, Date fechaBaja, Set<Usuario> educadoras,
			Set<Alumno> alumnos) {
		this.centro = centro;
		this.nombre = nombre;
		this.ubicacion = ubicacion;
		// this.fechaCreacion = fechaCreacion;
		this.fechaBaja = fechaBaja;
		this.educadoras = educadoras;
		this.alumnos = alumnos;
	}

	@Id
	@GeneratedValue(strategy = IDENTITY)
	@Column(name = "id", unique = true, nullable = false)
	@DocumentId
	public Long getId() {
		return this.id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@ManyToOne
	@JoinColumn(name = "centro_id", nullable = false)
	public Centro getCentro() {
		return this.centro;
	}

	public void setCentro(Centro centro) {
		this.centro = centro;
	}

	@Column(name = "nombre", nullable = false, length = 50)
	@Field
	public String getNombre() {
		return this.nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	@Column(name = "ubicacion")
	@Field
	public String getUbicacion() {
		return this.ubicacion;
	}

	public void setUbicacion(String ubicacion) {
		this.ubicacion = ubicacion;
	}

	// @Temporal(TemporalType.TIMESTAMP)
	// @Column(name = "fecha_creacion", nullable = false, length = 19)
	// public Date getFechaCreacion() {
	// return this.fechaCreacion;
	// }
	//
	// public void setFechaCreacion(Date fechaCreacion) {
	// this.fechaCreacion = fechaCreacion;
	// }

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "fecha_baja", length = 19)
	public Date getFechaBaja() {
		return this.fechaBaja;
	}

	public void setFechaBaja(Date fechaBaja) {
		this.fechaBaja = fechaBaja;
	}

	@ManyToMany
	@JoinTable(name = "educadora", joinColumns = { @JoinColumn(name = "aula_id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "usuario_id", nullable = false) })
	@JsonIgnore
	public Set<Usuario> getEducadoras() {
		return this.educadoras;
	}

	public void setEducadoras(Set<Usuario> educadoras) {
		this.educadoras = educadoras;
	}

	@Transient
	@JsonIgnore
	public List<Usuario> getEducadorasAsList() {
		return (getEducadoras() != null && getEducadoras().size() > 0) ? new ArrayList<Usuario>(getEducadoras())
				: Collections.EMPTY_LIST;
	}

	@OneToMany(mappedBy = "aula")
	@JsonIgnore
	public Set<Alumno> getAlumnos() {
		return this.alumnos;
	}

	public void setAlumnos(Set<Alumno> alumnos) {
		this.alumnos = alumnos;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((centro == null) ? 0 : centro.hashCode());
		result = prime * result + ((nombre == null) ? 0 : nombre.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Aula other = (Aula) obj;
		if (centro == null) {
			if (other.centro != null)
				return false;
		}
		else if (!centro.equals(other.centro))
			return false;
		if (nombre == null) {
			if (other.nombre != null)
				return false;
		}
		else if (!nombre.equals(other.nombre))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return new ToStringBuilder(this).append("id", id).append("centro", centro).append("nombre", nombre)
				.append("ubicacion", ubicacion).append("fechaBaja", fechaBaja).toString();
	}

}
